home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / blf082b / fug.c < prev    next >
C/C++ Source or Header  |  1993-11-15  |  15KB  |  610 lines

  1. /* 
  2.  *    BloufGate
  3.  *    Fido to Unix
  4.  *
  5.  *    Public Domain: may be copied and sold freely
  6.  */
  7.  
  8. #include    "blouf.h"
  9.  
  10. /* list of official internet primary domains (char **validdom) */
  11.  
  12. #include "validdom.h"
  13.  
  14. /* fixme ? */
  15. char msgtext[32700], msgheader[5000];
  16. FILE *news=NULL;
  17.  
  18. #define endofstr(a) a+strlen(a)
  19.  
  20. /* 
  21.  * case insensitive comparison of string ENDINGS 
  22.  */
  23.  
  24. int strendcmp(char *one, char *two)
  25. {
  26.     if(strlen(one)>strlen(two))
  27.         return stricmp(one+(strlen(one)-strlen(two)),two);
  28.     else
  29.         return stricmp(two+(strlen(two)-strlen(one)),one);
  30. }
  31.  
  32. /*
  33.  *    Gate mail message
  34.  */
  35.  
  36. int gatemail(BFIDOUSER *ffrom, char *to, char *subject, char *text,
  37.            struct tm *fidotime, char *fidomsgid)
  38. {
  39.     int i,error;
  40.     FILE *msg;
  41.     char *ptr;
  42.     char *domain;
  43.     time_t now;
  44.     
  45.     char from[BLFSTR];
  46.     char org[BLFSTR];
  47.     char date[BLFSTR];
  48.     char datenow[BLFSTR];
  49.     char uufrom[BLFSTR];
  50.     char uuuser[BLFSTR];
  51.  
  52.     i=0;
  53.     error=0;
  54.  
  55.     /* find organization and verify that node is listed */
  56.     ptr=findnode(ffrom->zone,ffrom->net,ffrom->node);
  57.     if(!ptr)
  58.     {
  59.         logline("!Message from unlisted node %d:%d/%d trashed.",
  60.                 ffrom->zone, ffrom->net, ffrom->node);
  61.         return FAIL;
  62.     }
  63.     strcpy(org,ptr);
  64.  
  65.     /* verify size */
  66.     if( ((int)strlen(text))>cf->outmaxsize )
  67.     {
  68.         bounce_fido(BOUNCE,"Message too big", ffrom, to);
  69.         return FAIL;
  70.     }
  71.  
  72.     /* fill from field */
  73.     fido2rfc(ffrom, from, uufrom, uuuser);
  74.  
  75.     /* find user in local user list */
  76.     ptr=finduser(to);
  77.     if(ptr)
  78.          strcpy(to, ptr);
  79.     
  80.     /* check to field */
  81.     if(strchr(to,' '))
  82.     {
  83.         bounce_fido(BOUNCE,"Invalid address: space(s) in address string", ffrom, to);
  84.         return FAIL;
  85.     }
  86.     
  87.     if(strlen(to)<2)
  88.     {
  89.         bounce_fido(BOUNCE,"No address.",ffrom,to);
  90.         return FAIL;
  91.     }
  92.  
  93.     if(strchr(to,'@') && strchr(to,'!'))
  94.     {
  95.         bounce_fido(WARNING,"Bang and domain mix, use %",ffrom, to);
  96.     }
  97.  
  98.     /* Get primary domain */
  99.     domain=strchr(to,'@');
  100.     if(domain)
  101.     {
  102.         if(cf->tunnelwarning==TRUE)
  103.         {
  104.             if(strendcmp(domain,finddomain(cf->o_zone,cf->o_net,cf->o_node))==0)
  105.             {
  106.                 bounce_fido(BOUNCE,"FTN to FTN tunnelling through the Internet illegal",
  107.                             ffrom,to);
  108.                 return FAIL;
  109.             }
  110.         }    
  111.  
  112.         domain=strrchr(++domain,'.');
  113.         if(domain)
  114.         {
  115.             domain++; /* skip '.' */
  116.             if(*domain==0)
  117.             {
  118.                 bounce_fido(BOUNCE,"No domain: Address ending by '.'",
  119.                             ffrom,to);
  120.                 return FAIL;
  121.             }
  122.             if(cf->uucpwarning==TRUE)
  123.             {
  124.                 if(stricmp(domain,"uucp")==0)
  125.                     bounce_fido(WARNING,".UUCP fakedomain obsolate, use domain address",
  126.                                 ffrom, to);
  127.             }
  128.  
  129.             if(cf->bitnetwarning==TRUE)
  130.             {
  131.                 if(stricmp(domain,"bitnet")==0)
  132.                     bounce_fido(WARNING,"No agreement with bitnet gateway: msg may be lost",
  133.                                 ffrom, to);
  134.             }
  135.  
  136.             if(cf->checkdomain==TRUE)
  137.             {
  138.                 int i=0;
  139.                 while(validdom[i])
  140.                 {
  141.                     if(stricmp(domain,validdom[i++])==0)
  142.                         break;
  143.                 }
  144.                 if(validdom[i]==NULL)
  145.                 {
  146.                     bounce_fido(BOUNCE,"Invalid primary domain", ffrom, to);
  147.                     return FAIL;
  148.                 }
  149.             }
  150.         }
  151.     }
  152.  
  153.     /* date */
  154.     if(strncmp(cf->uuname,uufrom,(size_t)strlen(cf->uuname))==0)
  155.         strftime(date,BLFSTR,"%a, %d %b %y %H:%M:%S %z",fidotime);
  156.     else
  157.         strftime(date,BLFSTR,"%a, %d %b %y %H:%M:%S GMT",fidotime);
  158.     time(&now);
  159.     strftime(datenow,BLFSTR,"%a, %d %b %y %H:%M:%S %z",localtime(&now));
  160.         
  161.     /* open output file */
  162.     msg = create_rfcfile(cf->outrfc,"rfc");
  163.     if(!msg)
  164.     {
  165.         logline("*Can't create rfc file");
  166.         return FAIL;
  167.     }
  168.  
  169.     /* and now write it */
  170. #ifdef BATCHSMTP
  171.        /* BATCH SMTP Header */
  172.     fprintf(msg,"HELO suntopo.matups.fr\n"); /* fixme: get from config */
  173.     fprintf(msg,"MAIL FROM:<%s>\n",from);
  174.     fprintf(msg,"RCPT TO:<%s>\n",to);
  175.     fprintf(msg,"DATA\n");
  176. #endif
  177.     /*** Uucp FROM ***/
  178.     fprintf (msg, "From: %s (%s)\n", from, ffrom->name);
  179.     fprintf (msg, "Message-ID: <%s>\n", fidomsgid);
  180.     /*fprintf (msg, "Message-ID: <%s@%s.%s>\n", fidomsgid, cf->uuname,
  181.             finddomain(cf->o_zone,cf->o_net,cf->o_node));*/    
  182.     /* fprintf (msg, "Sender: bloufgate@%s.%s\n", cf->uuname,"fidonet.org"); */
  183.     fprintf (msg, "To: %s\n", to);
  184.     fprintf (msg, "Date: %s\n", date);
  185.     fprintf (msg, "Subject: %s\n", subject);
  186.     fprintf (msg, "Organization: Fido node %d:%d/%d: %s.\n",
  187.                         ffrom->zone,ffrom->net,ffrom->node,org);
  188.     fprintf (msg, "X-Mailer: %s version %s\n",ProgName,Version);
  189.     
  190.     if(cf->startrek==TRUE)
  191.     {
  192.         fprintf (msg,"X-Starship: USS Enterprise [NCC1701]\n");
  193.         fprintf (msg,"X-Stardate: 5982.1\n");
  194.     }     
  195.     
  196.     fputc ('\n', msg);
  197.  
  198.     /* msg itself */
  199.     mksoftcr (text);
  200.     fputs (text, msg);
  201.  
  202.     /* signature */
  203.     fprintf (msg, "\n---\n      %s\n", from);
  204.  
  205. #ifdef BATCHSMTP
  206.     fprintf(msg,".\nQUIT\n");
  207. #endif
  208.  
  209.     if(ferror(msg))
  210.         logline("*File error while writing rfc msg!!!!");
  211.  
  212.     fclose (msg);
  213.  
  214.     if(ffrom->point ==0)
  215.         logline ("+%s (%d:%d/%d) -> %s", ffrom->name, ffrom->zone, ffrom->net, ffrom->node, to);
  216.     else
  217.         logline ("+%s (%d:%d/%d.%d) -> %s", ffrom->name, ffrom->zone, ffrom->net, ffrom->node, ffrom->point, to);
  218.  
  219.     return SUCCESS;
  220. }
  221.  
  222. /* fixme, msgheader== buffer */
  223.  
  224. int gatenews(char *fidoarea, BFIDOUSER * orig, char *subject, struct tm *fidotime,
  225.                char *messageid, char *replymsgid, char *msgscan)
  226. {
  227.     char *kludge, tmp[BLFSTR];
  228.     char nixfrom[BLFSTR], uufrom[BLFSTR], uuuser[BLFSTR];
  229.     char date[BLFSTR];
  230.     char *org;
  231.     GATENEWS *mynews;
  232.  
  233.     if (news == NULL)
  234.     {
  235.         /* initialize the globalocal file pointer to the news batch */
  236.         news=create_rfcfile(cf->outrfc,"nws");
  237.         if(news==NULL)
  238.             return FAIL;
  239.     }
  240.  
  241.     /* Find fido group */
  242.     mynews = area_fido2unix(fidoarea);
  243.     if (mynews == NULL)
  244.     {
  245.         logline("!Bad area %s",fidoarea);
  246.         return FAIL;
  247.     }
  248.  
  249.     /* Moderated ? */
  250.     if(mynews->write==FALSE)
  251.     {
  252.         logline("-%s tried to write in %s (moderated).",
  253.                     orig->name,mynews->news);
  254.         return FAIL;
  255.     }
  256.  
  257.     /* check SEEN-BY */
  258.     kludge = strstr (msgscan, "\nSEEN-BY");
  259.     if (kludge == NULL)
  260.     {
  261.         logline ("!Trashing %s -> %s (no SEEN-BY)", orig->name, mynews->news);
  262.         return FAIL;
  263.     }
  264.  
  265.     /* find node number in origin */
  266.     kludge = strstr(msgscan, "* Origin:");
  267.     if(kludge)
  268.         kludge = strrchr(kludge,'(');
  269.     if (kludge == NULL)
  270.     {
  271.         logline ("!Trashing %s -> %s (no origin)", orig->name, mynews->news);
  272.         return FAIL;
  273.     }
  274.     kludge[-1] = '\0'; /* suppress node number in texte */
  275.  
  276.     while(*kludge)
  277.     {
  278.         if(isdigit(*kludge))
  279.             break;
  280.         kludge++;
  281.     }
  282.  
  283.     if(!*kludge)
  284.     {
  285.         logline ("!Trashing %s -> %s (no node number)", orig->name, mynews->news);
  286.         return FAIL;
  287.     }
  288.  
  289.     if(fido2ints(kludge,&orig->zone,&orig->net,&orig->node,&orig->point)==FAIL)
  290.     {
  291.         logline ("!Trashing %s -> %s (no valid node number)", orig->name, mynews->news);
  292.         return FAIL;
  293.     }
  294.  
  295.     /* check origin */
  296.     org=findnode(orig->zone,orig->net,orig->node);
  297.     if(org==NULL)
  298.     {
  299.         logline("-Trashing %s (%d:%d/%d) -> %s (unlisted node)",
  300.             orig->name,orig->zone,orig->net,orig->node,mynews->news);
  301.         return FAIL;
  302.     }
  303.  
  304.     /* don't send again messages from us */
  305.     if(orig->zone==cf->o_zone && orig->net==cf->o_net
  306.         && orig->node==cf->o_node && orig->point==cf->o_point)
  307.     {
  308.         logline("-Trashing %s -> %s (message from us!)",
  309.             orig->name,mynews->news);
  310.         return FAIL;
  311.     }
  312.  
  313.     kludge[-1] = '\0'; /* suppress node number in text */
  314.  
  315.     strftime(date,BLFSTR,"%a, %d %b %y %H:%M:%S GMT",fidotime);
  316.  
  317.     fido2rfc(orig,nixfrom,uufrom,uuuser);
  318.  
  319.     msgheader[0] = '\0';
  320.     if(cf->nopath==TRUE)
  321.         sprintf (endofstr(msgheader), "Path: %s\n", uuuser); /* no path => local processing */
  322.     else
  323.         sprintf (endofstr(msgheader), "Path: %s!%s\n", cf->uuname,uuuser);
  324.     sprintf (endofstr(msgheader), "From: %s (%s)\n", nixfrom, orig->name);
  325.  
  326.     sprintf (endofstr(msgheader), "Date: %s\n", date);
  327.     sprintf (endofstr(msgheader), "Subject: %s\n", subject);
  328.  
  329.     sprintf (endofstr(msgheader), "Sender: bloufgate@%s.%s\n", cf->uuname,
  330.     finddomain(cf->o_zone,cf->o_net,cf->o_node));
  331.  
  332.     strcpy (tmp, mynews->news);
  333.     tmp[strscan('.', mynews->news)] = '\0';
  334.     sprintf (endofstr(msgheader), "Distribution: %s\n", tmp);
  335.  
  336.     sprintf (endofstr(msgheader), "Message-ID: <%s>\n", messageid);
  337.  
  338.     /* fill In-Reply-To: */
  339.     if(*replymsgid)
  340.         sprintf (endofstr(msgheader), "In-Reply-To: %s\n", replymsgid);
  341.  
  342.     sprintf (endofstr(msgheader), "Newsgroups: %s\n", mynews->news);
  343.  
  344.     sprintf (endofstr(msgheader), "Organization: Fido node %d:%d/%d : %s\n",
  345.                     orig->zone, orig->net, orig->node, org);
  346.  
  347.     mksoftcr (msgscan);
  348.  
  349.     /* suppress tear line, fixme? */
  350.     kludge = max(strstr (msgscan, "\n--- "), strstr (msgscan, "\n---\n"));
  351.     if (kludge != NULL) {
  352.         *kludge = '\0';
  353.         /* display origin line text in sig. */
  354.         strncpy (tmp, strstr(kludge+1, " * Origin:") + 11, 75);
  355.         sprintf (&msgscan[strlen(msgscan)], "\n--- %s\n    %s\n", tmp, nixfrom);
  356.     }
  357.     else
  358.         sprintf (&msgscan[strlen(msgscan)], "\n---\n    %s\n", nixfrom);
  359.  
  360.     fprintf (news, "#! rnews %d\n", strlen(msgheader)+strlen(msgscan)+1);
  361.     fputs (msgheader, news);
  362.     fputc ('\n', news);
  363.     fputs (msgscan, news);
  364.  
  365.     /* don't log messages posted in fido.* uuname.* groups */
  366.     if (!token("fido.", mynews->news) && !token(cf->uuname, mynews->news))
  367.         logline ("+%s (%d:%d/%d.%d) -> %s", orig->name,
  368.                        orig->zone, orig->net, orig->node, orig->point, mynews->news);
  369.     else
  370.         printf("%s (%d:%d/%d.%d) -> %s\n", orig->name,
  371.             orig->zone, orig->net, orig->node, orig->point, mynews->news);
  372.  
  373.     return SUCCESS;
  374. }
  375.  
  376.  
  377. int process_packet(char *outbound)
  378. {
  379.     FILE *packet;
  380.     char *msgscan;
  381.     char fidomsgid[40],replymsgid[40];
  382.     BFIDOUSER orig;
  383.     char to[BLFSTR], subject[75], date[25], fidogrp[60];
  384.     char  pktheader[58];
  385.     char dum1[BLFSTR],dum2[BLFSTR];
  386.     char messageid[BLFSTR];
  387.     unsigned char c;
  388.     int i,j;
  389.     char *tmp;
  390.  
  391.     struct tm msgtime;
  392.     time_t timerid;
  393.  
  394.     int error=0;
  395.  
  396.     time (&timerid);
  397.  
  398.     printf("Processing packet %s.\n",outbound);
  399.  
  400.     packet = fopen (outbound, "rb");
  401.     if(packet == NULL)
  402.         return FAIL;
  403.  
  404.  
  405. /* fixme, skip packet header ?!?, read zone in pkt, 4dpacket support */
  406.     orig.zone=0;
  407.     if(fread(pktheader,58,1,packet)!=1)
  408.         error++;
  409.  
  410.             
  411.     while(!error)
  412.     {
  413.         orig.zone = cf->o_zone;
  414.         orig.point = 0;
  415.         *messageid=0;
  416.  
  417.         c = (unsigned char) fgetc(packet); /* end */
  418.         if (c==0)
  419.             break;
  420.  
  421.         /* else read packet header */
  422.         fgetc(packet);
  423.  
  424.         orig.node = fgetiw(packet);
  425.         if(fgetiw(packet)!=cf->td_node && cf->fourdpkt==FALSE) /* dest node */
  426.         {
  427.             logline("?Bad destination node in packet");
  428.             error++;
  429.         }
  430.         orig.net = fgetiw(packet);
  431.         if(fgetiw(packet)!=cf->td_net && cf->fourdpkt==FALSE)
  432.         {
  433.             logline("?Bad destination net in packet");
  434.             error++; /* dest net */
  435.         }
  436.         fgetiw(packet); /* attrb (fixme?) */
  437.         fgetiw(packet); /* cost */
  438.  
  439.         fgetf (date, 21, packet);
  440.         fgetf (to, 37, packet);
  441.         fgetf (orig.name, 37, packet);
  442.         fgetf (subject, 73, packet);
  443.         fgetf (msgtext, 32000, packet);
  444.  
  445. /* fixme check msg size */
  446.  
  447.         if (date[0] != 0 && orig.name[0] != 0 && !error)
  448.         {
  449.             strdate2tm(date, &msgtime);
  450.  
  451.             fidomsgid[0] = '\0';
  452.             replymsgid[0] = '\0';
  453.  
  454.             msgscan = msgtext;
  455.  
  456.             fidogrp[0] = '\0';
  457.  
  458.             /* find AREA: -> fidogroup */
  459.             if ((i=token("AREA:", msgscan))!=0)
  460.             {
  461.                 msgscan += i;
  462.                 tmp = msgscan;
  463.                 while ((*msgscan != '\n') && (*msgscan))
  464.                     msgscan++;
  465.                 *msgscan++ = '\0';
  466.                 strcpy (fidogrp, tmp);
  467.             }
  468.  
  469.             /* scan kludges */
  470.             while (*msgscan == '\01')
  471.             {
  472.                 tmp=++msgscan;
  473.  
  474.                 /* remove EOL */
  475.                 while ((*msgscan != '\n') && (*msgscan))
  476.                     msgscan++;
  477.                 *msgscan++='\0'; /* msgscan ptr to next line */
  478.  
  479.                 /* find FMPT, INTL, MSGID, REPLY? kludges */
  480.                 if ((i=token("FMPT", tmp))!=0)
  481.                     orig.point=atoi(tmp+i);
  482.  
  483.                 /* find and verify INTL kludge */
  484.                 if ((i=token("INTL", tmp))!=0)
  485.                 {
  486.                     int z,n,f,p;
  487.  
  488.                     if(fido2ints(tmp+i,&z,&n,&f,&p)==FAIL)
  489.                         error++;
  490.                     else
  491.                     {
  492.                         if((z!=cf->o_zone) || (z!=cf->o_node) || (z!=cf->o_net) || (z!=cf->o_point))
  493.                             error++;
  494.                         else
  495.                         {
  496.                             j=strscan(' ',tmp+i);
  497.                             if(i<0)
  498.                                 if(fido2ints(tmp+i+j,&orig.zone,&orig.node,&orig.net,&orig.point)==FAIL)
  499.                                     error++;
  500.                         }
  501.                     }
  502.  
  503.                     if(error)
  504.                         logline("!Message with invalid INTL kludge");
  505.                 }
  506.  
  507.                 /* convert message ID */
  508.                 if ((i=token("MSGID:", tmp))!=0)
  509.                 {
  510.                     if(sscanf (&tmp[i], "%s %s", dum1, dum2)==2)
  511.                     {
  512.                         if ((i=strscan('@', dum1)) > 0)
  513.                             dum1[i] = '\0';
  514.                         if((i=strscan(':', dum1)) > 0)
  515.                             dum1[i] = '_';
  516.                         sprintf (fidomsgid, "%s_%s", dum1, dum2);
  517.                         strlwr(fidomsgid);
  518.                     }
  519.                 }
  520.  
  521. #ifdef USE_RFCID
  522.                 /* news: use old message id on already gated mails */
  523.                 if ((i=token(RFCIDKLUDGE, tmp))!=0)
  524.                 {
  525.                     if(sscanf (&tmp[i], "%s", dum1)==1)
  526.                         strcpy(messageid,dum1);
  527.                 }
  528. #endif
  529.  
  530.                 if ((i=token("REPLY:", tmp))!=0)
  531.                 {
  532.                     sscanf (&tmp[i], "%s %s", dum1, dum2);
  533.                     if ((i=strscan('@', dum1)) > 0)
  534.                         dum1[i] = '\0';
  535.                     if ((i=strscan(':', dum1)) > 0)
  536.                         dum1[i] = '_';
  537.                     sprintf (replymsgid, "<%s_%s@%s>", dum1, dum2,
  538.                        finddomain(cf->o_zone,cf->o_net,cf->o_node));
  539.                 }
  540.             }
  541.  
  542.             /* default message id & reply id, locally generated for news */
  543.             if (fidomsgid[0] == '\0')
  544.                 sprintf (fidomsgid, "local_%d_%d/%d_%lx",
  545.                     cf->o_zone, cf->o_net, cf->o_node, timerid++);
  546.             
  547.             if(!*messageid)
  548.                 sprintf(messageid,"%s@%s",fidomsgid,
  549.                    finddomain(cf->o_zone,cf->o_net,cf->o_node));
  550.                     
  551.             /* Generate fake replymsgid */
  552.             if(replymsgid[0] == '\0')
  553.             {
  554.                 if ((to[0] != 0) && (stricmp("All", to) != 0))
  555.                 {
  556.                     if ((i=strscan('(', to)) != -1)
  557.                         to[i-1] = 0;
  558.                     sprintf(replymsgid,"%s's message", to);
  559.                 }
  560.             }
  561.             
  562.             /* handle mail to 'uucp' */
  563.             if (fidogrp[0]=='\0' && !stricmp(to, "uucp"))
  564.             {
  565.                 i=0;
  566.                 /* find to: on the first line */
  567.                 while ((*msgscan != '\n') && (*msgscan != '\0') && (i<BLFSTR))
  568.                     dum1[i++] = *msgscan++;
  569.                 dum1[i]='\0';
  570.                 if ((i=token ("To:", dum1))!=0)
  571.                     strcpy (to, &dum1[i]);
  572.                 else
  573.                     strcpy (to, dum1);
  574.                 msgscan++;
  575.              }
  576.  
  577.             if (fidogrp[0] == '\0')
  578.                 gatemail(&orig,to,subject,msgscan,&msgtime,messageid);
  579.             else
  580.                 gatenews(fidogrp, &orig, subject, &msgtime,messageid, replymsgid, msgscan);
  581.         }
  582.  
  583.     } /* end pkt loop */
  584.  
  585.     fclose(packet);
  586.     if(news)
  587.         fclose(news);
  588.     
  589.     /* rename bad packet */
  590.     if(error)
  591.     {
  592.         logline("*Renaming bad packet");
  593.         strcpy(dum1,outbound);
  594.         if(strlen(dum1)>3)
  595.         { /* pkt to bkt */
  596.             dum1[strlen(dum1)-3]='B';
  597.             rename(outbound,dum1);
  598.         }
  599.     }
  600.  
  601.     /* remove processed packet */
  602.     if(cf->keep==FALSE && !error)
  603.     {
  604.         if(remove (outbound))
  605.             logline("!Can't remove %s",outbound);
  606.     }
  607.  
  608.     return SUCCESS;
  609. }
  610.